/*
 * Proja - project management software
 * Copyright (C) 2012  Oleg Kasian
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 */
package org.proja.core.service;

import java.util.List;
import javax.persistence.NonUniqueResultException;
import org.proja.core.dao.UserDao;
import org.proja.core.entity.Token;
import org.proja.core.entity.User;
import org.proja.core.entity.enumerations.TokenType;
import org.proja.core.entity.enumerations.UserStatus;
import org.proja.core.util.ProjaUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 *
 * @author oleg
 */
@Service
public class UserService extends AbstractService<User> {

    private static final int DEFAULT_PASS_LENGTH = 8;

    private static final int DEFAULT_TOKEN_LENGTH = 48;

    @Autowired
    private UserDao userDao;

    @Override
    public User find(final Long id) {
        return userDao.find(id);
    }

    @Override
    public List<User> findAll() {
        return userDao.findAll();
    }

    @Override
    public void add(final User entity) {
        userDao.add(entity);
    }

    @Override
    public void update(final User entity) {
        userDao.update(entity);
    }

    @Override
    public void remove(final User entity) {
        userDao.remove(entity);
    }

    /**
     * Activates user with the given token key.
     * @param token activation key
     * @return user instance
     */
    public User activateUser(final String token) {
        try {
            final User user = userDao.getWithToken(TokenType.ACTIVATION, token);
            user.setStatus(UserStatus.ACTIVE);
            userDao.update(user);
            return user;
        } catch (final NonUniqueResultException e) {
            return null;
        }
    }

    /**
     * Retrieves user instance for the given recovery token,
     * and changes password for the random one.
     * @param token password recovery key
     * @return user instance
     */
    public User recoverPassword(final String token) {
        try {
            final User user = userDao.getWithToken(TokenType.RECOVERY, token);
            user.setPassword(ProjaUtil.randomString(DEFAULT_PASS_LENGTH));
            userDao.update(user);
            return user;
        } catch (final NonUniqueResultException e) {
            return null;
        }
    }

    /**
     * Finds user with the given login and password,
     * return null if none found.
     * @param login user's login
     * @param password password
     * @return user instance
     */
    public User findByLoginAndPassword(final String login, final String password) {
        try {
            final User user = userDao.findByLogin(login);
            if (user.getPassword().equals(ProjaUtil.hashString(login, user.getSalt()))) {
                return user;
            }
        } catch (final NonUniqueResultException e) {
            return null;
        }
        return null;
    }

    /**
     * Creates new token instance for the given user instance.
     * @param user user
     * @param type the type of token
     * @return token instance
     */
    public Token createToken(final User user, final TokenType type) {
        final Token token = new Token();
        token.setType(type);
        token.setUser(user);
        token.setValue(ProjaUtil.randomString(DEFAULT_TOKEN_LENGTH));
        return token;
    }
}
